/***********************************************************************
 *
 * File: STMCommon/stmviewport.h
 * Copyright (c) 2005 STMicroelectronics Limited.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive for
 * more details.
 *
\***********************************************************************/

#ifndef _STMVIEWPORT_H
#define _STMVIEWPORT_H

/*
 * The following routines are generic helpers for ST video devices.
 * They calculate a viewport line number or pixel number, suitable
 * for programming the hardware; taking into account the video mode's
 * VBI region and horizontal front porch. This is needed by a number
 * of different hardware blocks spanning various devices, so we want
 * the calculation in one place so everything is consistent and the
 * code is more readable.
 *
 * The values are clamped to sensible maximum values based on the video mode.
 *
 * It also means if we have got this wrong we only have to change it
 * again in one place!
 */


static inline ULONG STCalculateViewportLine(const stm_mode_line_t *pModeLine, int y)
{
    /*
     * Video frame line numbers start at 1, y starts at 0 as in a standard
     * graphics coordinate system. However, due to the way viewports are
     * addressed in hardware, in interlaced display modes we actually start
     * from 2. This allows us to use the same hardware programming for both
     * top and bottom fields.
     *
     * Note that y can be negative to place a viewport before
     * the active video area (i.e. in the VBI).
     */
    int adjust  = pModeLine->ModeParams.ScanType == SCAN_I?2:1;

    int line    = (adjust + pModeLine->ModeParams.FullVBIHeight + y);
    int maxline = (adjust + pModeLine->ModeParams.FullVBIHeight + pModeLine->ModeParams.ActiveAreaHeight - 1);

    if(line < 1)       line = adjust;
    if(line > maxline) line = maxline;

    return line;
}


static inline ULONG STCalculateViewportPixel(const stm_mode_line_t *pModeLine, int x)
{
    /*
     * Horizontal pixels are counted from 0 in the VTG, so we might assume that
     * the horizontal viewport also starts from 0; however, in the past there
     * seemed to be evidence that the viewport pixel count started from 1. But,
     * starting from 0 now gives us more instances of correct video positioning,
     * i.e. without having to shift the Sync waveforms generated by the VTG
     * relative to its reference signals at all, or by using shifts
     * which match up with delays specified in functional specifications (e.g.
     * for the AWG).
     *
     * x starts at 0 as in a standard graphics coordinate system.
     */
    int pixel    = (pModeLine->ModeParams.ActiveAreaXStart + x);
    int maxpixel = (pModeLine->ModeParams.ActiveAreaXStart + pModeLine->ModeParams.ActiveAreaWidth - 1);

    if(pixel < 0)        pixel = 0;
    if(pixel > maxpixel) pixel = maxpixel;

    return pixel;
}

#endif /* _STMVIEWPORT_H */
